Skip to content

fix(changelog): handle triple-backtick code fences in sanitizeChangelogEntry#13724

Closed
devin-ai-integration[bot] wants to merge 2 commits into
mainfrom
devin/1773922414-fix-changelog-sanitizer
Closed

fix(changelog): handle triple-backtick code fences in sanitizeChangelogEntry#13724
devin-ai-integration[bot] wants to merge 2 commits into
mainfrom
devin/1773922414-fix-changelog-sanitizer

Conversation

@devin-ai-integration

@devin-ai-integration devin-ai-integration Bot commented Mar 19, 2026

Copy link
Copy Markdown
Contributor

Description

Refs fern-api/docs#4342

Fixes a bug where sanitizeChangelogEntry double-wrapped angle-bracket types (e.g., Consumer<String>) in backticks when the changelog entry contained a fenced code block. This caused MDX parsing failures in the docs repo (the <String> was interpreted as a JSX tag).

Changes Made

  • Added a preliminary split on triple-backtick fenced code blocks in sanitizeChangelogEntry, preserving them verbatim before processing remaining text with the existing inline-backtick logic
  • Extracted the original inline-backtick processing into a sanitizeInlinePart helper
  • Added 3 test cases covering fenced code blocks

Root Cause

The function split only on single-backtick spans (`...`). When a changelog entry contained a ```java...``` block, the triple backticks confused the single-backtick regex, throwing off parity. Segments that should have been recognized as "inside backticks" were treated as plain text, causing wrapAngleBracketTypes to add redundant backticks around types like Consumer<String>.

The approach mirrors what angleBracketValidator.ts already does — strip fenced blocks before processing inline code.

Updates since last revision

  • Improved the fenced code block regex from /(```[\s\S]*?```)/g to /(```[^\n]*\n[\s\S]*?\n```)/g per Graphite review feedback. The stricter regex requires newlines around fence content, preventing triple backticks inside a string literal (e.g., const x = "```") from prematurely terminating the match.

Testing

  • Unit tests added (3 new cases: double-wrap after fence, preserve fence verbatim, wrap outside but not inside fence)
  • All 97 existing tests in @fern-api/core-utils still pass
  • biome check passes

Human Review Checklist

  • Verify the stricter regex /(```[^\n]*\n[\s\S]*?\n```)/g handles all expected fenced block formats (e.g., with/without language identifier, trailing whitespace)
  • Confirm the Java SDK 4.0.0 entry in generators/java/sdk/versions.yml (which triggered the original docs CI failure) would now produce correct MDX output when the changelog generation pipeline runs

Link to Devin session: https://app.devin.ai/sessions/5151f683b2dd4b19b266c84cb1aa999a

The sanitizer only split on single-backtick inline code spans, so
triple-backtick fenced code blocks (common in Java changelog entries)
threw off backtick parity. This caused later inline code spans like
`onMessage(Consumer<String>)` to be treated as plain text, and
Consumer<String> got double-wrapped in backticks — breaking MDX parsing
in the docs repo.

Fix: split on fenced code blocks first (preserving them verbatim),
then process each remaining segment with the existing inline-backtick
logic.

Co-Authored-By: unknown <>
@devin-ai-integration

Copy link
Copy Markdown
Contributor Author

🤖 Devin AI Engineer

I'll be helping with this pull request! Here's what you should know:

✅ I will automatically:

  • Address comments on this PR. Add '(aside)' to your comment to have me ignore it.
  • Look at CI failures and help fix them

Note: I can only respond to comments from users who have write access to this repository.

⚙️ Control Options:

  • Disable automatic comment and CI monitoring

@claude claude Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Code review skipped — your organization's overage spend limit has been reached.

Code review is billed via overage credits. To resume reviews, an organization admin can raise the monthly limit in Settings → Usage.

Once credits are available, reopen this pull request to trigger a review.

// First, split on triple-backtick fenced code blocks so they are never
// processed by the inline-backtick logic (which only understands single
// backtick pairs and gets confused by the three-backtick delimiters).
const fenceParts = entry.split(/(```[\s\S]*?```)/g);

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The regex /(```[\s\S]*?```)/g will incorrectly split fenced code blocks that contain triple backticks in their content. For example, a changelog entry like:

Example:
```js
const example = "```";

The regex will match from the opening ``` to the first ``` inside the string literal, breaking the fence mid-block. The remaining text `";\n``` ` will be treated as plain text and incorrectly processed.

**Fix:** Use a more specific regex that matches the fence opening with optional language identifier:
```typescript
const fenceParts = entry.split(/(```[^\n]*\n[\s\S]*?\n```)/g);

Or handle the newline requirement:

const fenceParts = entry.split(/(```(?:[^`]|`(?!``))*```)/gs);
Suggested change
const fenceParts = entry.split(/(```[\s\S]*?```)/g);
const fenceParts = entry.split(/(```[^\n]*\n[\s\S]*?\n```)/g);

Spotted by Graphite

Fix in Graphite


Is this helpful? React 👍 or 👎 to let us know.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good catch — applied the suggested stricter regex /(```[^\n]*\n[\s\S]*?\n```)/g in c432cd1. This requires newlines around the fence content, preventing triple backticks inside a string literal from prematurely terminating the match.

Address Graphite review: require newlines around fence content so that
triple backticks inside code (e.g. a string literal containing ```)
do not prematurely terminate the match.

Co-Authored-By: unknown <>
@devin-ai-integration devin-ai-integration Bot changed the title fix: handle triple-backtick code fences in sanitizeChangelogEntry fix(changelog): handle triple-backtick code fences in sanitizeChangelogEntry Mar 19, 2026
@davidkonigsberg davidkonigsberg deleted the devin/1773922414-fix-changelog-sanitizer branch March 19, 2026 12:45
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant